/*
 * ObjectUtils
 * 
 * Project: Oxygen
 * 
 * Copyright 2010 by Firmenich SA
 * Rue de la Bergère 7, 1217 Meyrin
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Firmenich SA. ("Confidential Information"). You
 * shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license
 * agreement you entered into with Firmenich.
 */
package utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utils for object.
 * 
 * @author phd
 * 
 */
public class ObjectUtils {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(ObjectUtils.class);

	/**
	 * Private constructor to avoid instanciation.
	 */
	private ObjectUtils() {
		// do something
	}

	/**
	 * Deeply copy an object.
	 * 
	 * @param source
	 *            Source object.
	 * @return Deep copy of the <code>source</code> object.
	 */
	public static Serializable copy(Serializable source) {
		Serializable result = null;
		try {
			byte[] b = serialize(source);
			result = unserialize(b);
		} catch (Exception e) {
			LOGGER.error("Error in copying object", e);
			throw new RuntimeException(e);
		}
		return result;
	}

	private static byte[] serialize(Serializable object) throws IOException {
		ByteArrayOutputStream stream = null;
		ObjectOutputStream out = null;
		try {
			stream = new ByteArrayOutputStream();
			out = new ObjectOutputStream(stream);
			out.writeObject(object);
			out.flush();
			return stream.toByteArray();
		} finally {
			if (stream != null) {
				stream.close();
			}
			if (out != null) {
				out.close();
			}
		}
	}

	private static Serializable unserialize(byte[] array) throws IOException,
			ClassNotFoundException {
		ByteArrayInputStream stream = null;
		ObjectInputStream in = null;
		try {
			stream = new ByteArrayInputStream(array);
			in = new ObjectInputStream(stream);
			return (Serializable) in.readObject();
		} finally {
			if (stream != null) {
				stream.close();
			}
			if (in != null) {
				in.close();
			}
		}
	}
}
